package com.freeheart.validation.constraintvalidators.recent;


import com.freeheart.validation.constraints.Recent;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.extern.slf4j.Slf4j;

/**
 * 对{@code com.freeheart.validation.constraints.Recent}注解校验的ConstraintValidator
 *
 * @author: EmperorHeart
 * @date: 2025/4/28 23:00
 * @description
 */
@Slf4j
public abstract class AbstractRecentConstraintValidator implements ConstraintValidator<Recent, Object> {
    /**
     * Recent注解的属性类
     */
    protected RecentProperties recentProperties;

    @Override
    public void initialize(Recent constraintAnnotation) {
        this.recentProperties = new RecentProperties(constraintAnnotation);
    }


    @Override
    public boolean isValid(Object object, ConstraintValidatorContext context) {
        boolean notValid = recentProperties.notValid(object);
        if (notValid) {
            return true;
        }
        long gap = recentProperties.isContainFuture() ?
                Math.abs(computeGap(object, recentProperties)) :
                computeGap(object, recentProperties);
        if (recentProperties.pass(gap)) {
            return true;
        }
        validFail(context);
        return false;
    }

    /**
     * 子类来实现：计算时间差的逻辑
     *
     * @param object 当前值
     * @param rp     封装Recent属性的类：RecentProperties
     * @return 时间差
     */
    protected abstract long computeGap(Object object, RecentProperties rp);

    /**
     * 将失败后的描述信息填充进上下文中
     *
     * @param context ConstraintValidatorContext
     */
    public void validFail(ConstraintValidatorContext context) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(recentProperties.getMsg()).addConstraintViolation();
    }

}
